/*
 * @Descripttion:
 * @version: v1.0
 * @Author: Zc
 * @Date: 2022/4/10 14:51
 * @LastEditors: Zc
 * @LastEditTime: 2022/4/10 14:51
 */
import { reactive } from 'vue'
import RouteConst from '../../router/routeConst'
import {
    assign3,
    callLater,
    deepCopyObject,
    getLocalParam,
    getLocationPath,
    getSelectItem,
    hasOwnProp
} from '../utils/normalUtils'
import {
    clearPageCatch,
    clearSystemCatch, initPermission,
    initSystemCatch, permissionState,
    saveSystemCatch
} from './PermissionManager'
import { changeRoute, changeRouteExecute, initMainRoutes, initNaveMenu } from '../../router'
import { sendServiceData } from '../service'
import { queryUserInfoApi, queryUserPermissionApi } from '../service/api/userApi'
import { appEmbedInit, initEmbedState, initEmbedUserInfo } from './appEmbedManager'
import { initSysTheme } from './ThemeManager'

const URL_FILE = (import.meta as any).env.VITE_APP_FILE_API !== null
    ? (import.meta as any).env.VITE_APP_FILE_API?.toString()
    : ''

export interface IAppState {
    /**
     * 全局加载状态
     */
    isLoading: boolean,
    /**
     * 系统名称
     */
    name: string,
    /**
     * 系统别名
     */
    alias: string,
    /**
     * 系统平台名称
     */
    platform: string,
    /**
     * 系统id
     */
    code: string,
    /**
     * 渲染模式 0默认
     */
    mode:any,
    /**
     * 是否嵌入模式
     */
    embed: any,
    /**
     * 是否同域嵌入
     */
    embedSameDomain:boolean,
    /**
     * 嵌入通信唯一标识
     */
    embedKey:string,
    /**
     * 嵌入视图类型 1内容全铺满
     */
    embedType:string,
    /**
     * 本地调试模式
     */
    debugMode: boolean,
    /**
     * 系统标题
     */
    title: string,
    /**
     * 是否已经鉴权完成
     */
    userInit: boolean,
    /**
     * 当前主题 light dark
     */
    theme:string,
    /**
     * 显示换肤功能
     */
    themeDisabled:boolean,
    /**
     * 是否菜单最小化
     */
    menuMini: boolean,
    /**
     *  菜单列表
     */
    menuList: any[],
    /**
     *  模式为导航模式时(mode=1) 存储所有系统的导航菜单
     */
    navMenuList: any[],
    /**
     * 主导航模式 不同主菜单作为一个系统显示 二级菜单作为一级导航
     */
    showMenus:any[],
    /**
     * 菜单扁平化
     */
    menuMap: any,
    /**
     * 默认路由
     */
    defaultRoute: string,
    /**
     * 当前登录用户
     */
    currentUser: {
        userId: any,
        userName: string,
        nickName: string,
        email: string,
        phonenumber: any,
        admin: any,
        avatar: any,
        depts: any[],
        remark: any,
        roles: any[],
        sex: any,
        deptType: any, // 部门类型
        deptId: any, // 部门ID
        deptName: any, // 单位名称
        deptData: any, // 部门名称
        [props:string]:any
    },
    /**
     * 文件服务器地址
     */
    fileServiceUrl: string,
    /**
     * 配置信息
     */
    config: any,
    baseUrl: string,
    /**
     * 兼容原有逻辑添加缓存对象
     */
    oldCatch:{
        userInfo:any,
        btnInfo:any
    },
    [props:string]:any
}
// 配置信息
const evnData:any = (import.meta as any).env

// 系统状态
export const appState:IAppState = reactive({
    // 顶层加载状态
    isLoading: false,
    // ---------------------------------------------------------- pub ---------------------------------
    code: evnData.VITE_APP_SYS_CODE || 'newu-user-service',
    name: evnData.VITE_APP_SYS_NAME,
    alias: evnData.VITE_APP_SYS_ALIAS,
    platform: evnData.VITE_APP_SYS_PLATFORM,
    mode: Number(evnData.VITE_APP_SYS_MODE), // 系统模式 0默认 1兼容旧版导航
    // ---------------------------------------------------------- pub ---------------------------------
    debugMode: false, // 纯本地测试模式 不做验证
    title: '',
    userInit: false,
    theme: 'light',
    themeDisabled:false,
    // ---------------------------------------------------------- embed ---------------------------------
    embed: false, // 是否嵌入模式
    embedSameDomain: false, // 是否同域
    embedType: '', // 嵌入类型 0整体嵌入 1不包含头和菜单
    embedKey: '', // 嵌入模式唯一值 如果需要控制菜单等需要配置
    // ---------------------------------------------------------- menu ---------------------------------
    menuMini: false, // 最小化菜单
    showMenus: [], // 显示菜单列表
    menuList: [], // 菜单数据
    navMenuList: [], // 系统导航菜单
    menuMap: {}, // 扁平化菜单列表
    defaultRoute: '', // 默认路由
    // ---------------------------------------------------------- menu end ---------------------------------
    // 当前登录用户
    currentUser: {
        userId: '',
        userName: '',
        nickName: '',
        email: '',
        phonenumber: '',
        admin: false,
        avatar: '',
        depts: [],
        remark: '',
        roles: [],
        sex: '1',
        deptType: '', // 部门类型
        deptId: '', // 部门ID
        deptName: '', // 单位名称
        deptData: null // 部门名称
    },
    fileServiceUrl: URL_FILE,
    iconPath: 'static/icon/',
    config: {
        platform: '',
        name: '',
        alias: '',
        code: '',
        fileSizeLimit: 50000
    },
    baseUrl: evnData.VITE_APP_BASE_API!.toString() || '',
    oldCatch: {
        userInfo: null,
        btnInfo: []
    }
})

/**
 * 系统初始化
 */
export const initApp = async () => {
    // 初始化配置信息
    initConfig()
    // 初始化主题
    initSysTheme()
    // 解析是否为嵌入模式
    initSysEmbed()
    // 非嵌入模式
    if (!appState.embed) {
        // 初始化缓存信息
        const catchInfo = initSystemCatch()
        // 如果有token 初始化用户信息
        if (catchInfo) await initUserLoginInfo(catchInfo, false)
    }
}

/**
 * 初始化配置信息
 */
function initConfig() {
    // 初始化配置信息
    const config: any = (window as any).SYSTEMCONFIG || {}
    assign3(appState.config, config)
    // 保证名称等信息发布后还可配置
    if (config.code)appState.code = config.code
    if (config.name)appState.name = config.name
    if (config.alias)appState.alias = config.alias
    if (config.platform)appState.platform = config.platform
    if (config.fileServiceUrl)appState.fileServiceUrl = config.fileServiceUrl
    appState.iconPath = getLocationPath(config.iconPath || 'static/icon/')
}

/**
 * 解析嵌入模式参数
 */
function initSysEmbed() {
    const params = initEmbedState(appState.code)
    Object.assign(appState, params)
}

/**
 * 显示系统最外层状态
 * @param value
 */
export function showAppLoading(value = true) {
    const loadingDom:any = document.getElementById('app-loader-wrapper')
    loadingDom.style.display = value ? 'flex' : 'none'
}

/**
 * 初始化用户基本信息 衔接下以前的配置 保证token可取 temp?
 * @param userInfo
 * @param catchData
 * @param userData
 * @param menuData
 */
export async function initUserLoginInfo(userInfo:any, catchData = true, userData:any = null, menuData:any = null) {
    appState.currentUser.userName = userInfo.userName
    appState.currentUser.userId = userInfo.userId
    if (catchData)saveSystemCatch(userInfo)
    // 获取用户最新权限结合
    if (!userData) {
        const result = await sendServiceData(queryUserInfoApi, {})
        if (!result || !result.user) {
            exitApp()
            return
        }
        userData = result
    }
    // 解析用户基本信息
    initUserBaseInfo(userData)
    // 权限信息
    initPermission(userData.permissionList || [])
     // 查询路由信息
    if (!menuData) {
        const menus = await sendServiceData(queryUserPermissionApi, {})
        menuData = menus
    }
    // 重新初始化路由
    const { menus, menuMap, defaultRoute } = initMainRoutes(menuData )
    appState.menuList = menus
    appState.menuMap = menuMap
    appState.defaultRoute = defaultRoute
    // 设置默认路由
    appState.userInit = true
}

/**
 * 解析用户信息
 * @param userData
 */
function initUserBaseInfo(userData:any) {
    // 这个机构列表包含了所有的子机构 只需要主机构
    if (userData.user && userData.user.depts && userData.user.depts.length > 0 && userData.user.depts[0]) {
        userData.user.depts = [userData.user.depts[0]]
    }
    // 初始化用户基本信息
    Object.assign(appState.currentUser, userData.user)
}

// ##################################################################################### public route control #####################################
/**
 * 系统视图初始化完成处理
 */
export async function appMounted() {
    // 隐藏加载状态
    showAppLoading(false)
    // 嵌入模式
    if (appState.embed) appEmbedInit()
}

/**
 * 退出系统
 */
export async function exitApp() {
    clearSystemCatch()
    initReloadSystem()
}

/**
 * 重新加载系统页面
 */
export const initReloadSystem = async (path = '', reload = true) => {
    clearPageCatch()
    if (path)window.sessionStorage.setItem('login', path)
    await changeRoute(RouteConst.LOGIN)
    if (reload) window.location.reload()
}

/**
 * 重新加载系统页面
 */
export const changeBackToLogin = async (path = '') => {
    clearPageCatch()
    if (path)window.sessionStorage.setItem('login', path)
     changeRoute(RouteConst.LOGIN)
}

// ##################################################################################### manager method #####################################

